home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_asm / exe2com / exe2com.asm next >
Encoding:
Assembly Source File  |  1987-04-27  |  12.0 KB  |  279 lines

  1. program       group     code
  2. code          segment   para public 'code'
  3.               assume    cs:program,ds:program
  4. ;
  5.               org       80h
  6. parm_len      db        ?
  7. parm          label     byte
  8.               org       100h
  9. ;
  10. begin:        jmp       main
  11. help_msg      db        'usage: exe2com file1 [file2]'
  12. crlf          db        13,10,'$'
  13. input_err     db        'exe2com: unable to find input file $'
  14. output_err    db        'exe2com: unable to open output file $'
  15. err_1         db        'invalid EXE file signature',13,10,'$'
  16. err_2         db        'EXE has relocatable items',13,10,'$'
  17. err_3         db        'EXE has stack segment',13,10,'$'
  18. err_4         db        'EXE has nonzero CS',13,10,'$'
  19. err_5         db        'IP not 0 or 100H',13,10,'$'
  20. err_6         db        'program exceeds 64K',13,10,'$'
  21. err_7         db        'error reading EXE file',13,10,'$'
  22. err_8         db        'error writing COM file',13,10,'$'
  23. cvt_msg_1     db        'converting $'
  24. cvt_msg_2     db        'to $'
  25. warn_msg      db        'WARNING: COM file must have initial IP of 100H',13,10,'$'
  26. com_ext       db        '.COM'
  27. exe_ext       db        '.EXE'
  28. sys_ext       db        '.SYS'
  29. ;
  30. ; NOTE: Storage for file names allows for maximum of 128 byte drive/path/name
  31. ;       plus 00H to end asciiz string and '$' to end DOS function 09H
  32. ;
  33. file_1        db        130 dup (0)
  34. file_2        db        130 dup (0)
  35. handle_1      dw        0
  36. handle_2      dw        0
  37. file_hdr      dw        14 dup (0)
  38. file_buf      db        512 dup (0)
  39. hdr_size      dw        0
  40. code_size     dw        0
  41. init          proc      near
  42.               xor       cx,cx
  43.               mov       cl,parm_len    ;get length of command trailer from PSP
  44.               inc       cx
  45.               lea       si,parm
  46.               lea       di,file_1
  47.               call      get_name       ;get input file name
  48.               lea       di,file_2
  49.               call      get_name       ;get output file name
  50.               xor       ax,ax
  51.               cmp       al,file_1      ;if no input file
  52.               jz        bad_parm       ;exit with error message
  53.               cmp       al,file_2      ;if no output file
  54.               jz        no_file_2      ;use same name as input
  55.               jmp       short check_ext
  56. no_file_2:    lea       si,file_1
  57.               lea       di,file_2
  58.               mov       cx,130
  59. move_filnm:   lodsb                    ;get byte from input file name
  60.               cmp       al,'.'
  61.               jz        end_move       ;don't move file extension
  62.               cmp       al,0
  63. end_move:     stosb                    ;store byte in output file name
  64.               loopnz    move_filnm     ;if not '.' or 00h get next
  65.               dec       di
  66.               mov       ax,2400h       ;end with 00H and $
  67.               stosw
  68. check_ext_1:  lea       si,file_1      ;if no extension
  69.               lea       dx,exe_ext     ;on input file
  70.               mov       cx,130         ;default to EXE
  71.               call      check_ext
  72. check_ext_2:  lea       si,file_2      ;if no extension
  73.               lea       dx,com_ext     ;on output file
  74.               mov       cx,130         ;default to EXE
  75.               call      check_ext
  76. end_init:     ret
  77. bad_parm:     lea       dx,help_msg    ;no files
  78. error_end:    mov       ah,9           ;display error message
  79.               int       21h
  80.               mov       ax,4c01h       ;terminate with return code 1
  81.               int       21h
  82. init          endp
  83. get_name      proc      near                     
  84.               push      di             ;save destination address
  85.               mov       di,si
  86.               mov       al,' '
  87.               repz      scasb          ;scan for first non-blank
  88.               dec       di
  89.               mov       si,di
  90.               inc       cx
  91.               pop       di             ;restore destination
  92. get_byte:     lodsb
  93.               cmp       al,' '         ;stop moving if blank
  94.               jz        short end_name
  95.               cmp       al,13          ;<cr> is end of command trailer
  96.               jz        short end_name
  97.               cmp       al,'a'         ;convert to upper case
  98.               jb        store_byte
  99.               cmp       al,'z'
  100.               ja        store_byte
  101.               sub       al,32
  102. store_byte:   stosb
  103.               loop      get_byte
  104. end_name:     dec       si
  105.               mov       ax,2400h       ;end with 00H and $
  106.               stosw
  107.               ret
  108. get_name      endp
  109. check_ext     proc      near
  110.               lodsb
  111.               cmp       al,'.'         ;if '.' found then file has ext
  112.               jz        check_end
  113.               cmp       al,0           ;end of file name
  114.               loopnz    check_ext
  115.               dec       si
  116.               mov       di,si
  117.               mov       si,dx          ;DX contains address of default
  118.               mov       cx,4
  119.               rep       movsb          ;move default extension
  120.               mov       ax,2400h       ;end with 00H and '$'
  121.               stosw
  122. check_end:    ret
  123. check_ext     endp
  124. read_hdr      proc      near
  125.               lea       dx,file_1
  126.               mov       ax,3d00h       ;open the input file
  127.               int       21h
  128.               jb        bad_file_1     ;error on open
  129.               mov       handle_1,ax    ;save handle
  130.               lea       dx,file_hdr
  131.               mov       bx,handle_1
  132.               mov       cx,28          ;read 28 bytes
  133.               mov       ah,3fh         ;of fixed header information
  134.               int       21h
  135.               jnb       check_hdr
  136.               jmp       bad_read       ;error on read
  137. check_hdr:    mov       ax,'ZM'
  138.               cmp       ax,file_hdr    ;all EXE files begin with 'MZ'
  139.               jnz       not_exe
  140.               mov       ax,0
  141.               cmp       ax,file_hdr+6  ;number of relocatable items
  142.               jnz       has_relo       ;must be 0
  143.               mov       ax,file_hdr+14
  144.               or        ax,file_hdr+16 ;SS and SP must be 0
  145.               jnz       has_ss
  146.               cmp       ax,file_hdr+22 ;CS offset must be 0
  147.               jnz       has_cs
  148.               mov       ax,file_hdr+20 ;initial IP
  149.               cmp       ax,100h        ;must be 100H for COM file
  150.               jz        hdr_ok
  151.               cmp       ax,0           ;IP must be 0 or 100H
  152.               jnz       bad_ip
  153.               call      sys_file       ;if IP=0 output will be .SYS file
  154. hdr_ok:       mov       ax,file_hdr+8
  155.               mov       cx,4           ;size of EXE file header
  156.               shl       ax,cl
  157.               mov       hdr_size,ax
  158.               mov       ax,file_hdr+4  ;number of 512 byte pages
  159.               dec       ax             ;in EXE file
  160.               mov       bx,512
  161.               mul       bx             ;multiply by 512
  162.               add       ax,file_hdr+2  ;add # of bytes in last page
  163.               adc       dx,0
  164.               sub       ax,hdr_size    ;subtract header size
  165.               sbb       dx,0           ;to get size of program
  166.               jnz       too_big        ;cannot be > 64K
  167.               mov       code_size,ax
  168.               ret
  169. bad_file_1:   lea       dx,input_err   ;couldn't open input file
  170.               jmp       error_end
  171. bad_file_2:   lea       dx,output_err  ;couldn't open output file
  172.               jmp       error_end
  173. not_exe:      lea       dx,err_1       ;not a valid EXE file
  174.               jmp       error_end
  175. has_relo:     lea       dx,err_2       ;EXE has relocatable items
  176.               jmp       error_end
  177. has_ss:       lea       dx,err_3       ;EXE contains a stack segment
  178.               jmp       error_end
  179. has_cs:       lea       dx,err_4       ;EXE contains a CS offset
  180.               jmp       error_end
  181. bad_ip:       lea       dx,err_5       ;IP not 0 or 100H
  182.               jmp       error_end
  183. too_big:      lea       dx,err_6       ;file > 64K
  184.               jmp       error_end
  185. bad_read:     lea       dx,err_7       ;error reading input file
  186.               jmp       error_end
  187. bad_write:    lea       dx,err_8       ;error reading output file
  188. del_file:     push      dx             ;conversion failed
  189.               mov       bx,handle_1    ;close input file
  190.               mov       ah,3eh
  191.               int       21h
  192.               mov       bx,handle_2    ;close output file
  193.               int       21h
  194.               lea       dx,file_2
  195.               mov       ah,41h         ;delete output file
  196.               int       21h
  197.               pop       dx
  198.               jmp       error_end
  199. read_hdr      endp
  200. convert       proc      near
  201.               lea       dx,file_2      ;create output file
  202.               xor       cx,cx
  203.               mov       ah,3ch
  204.               int       21h
  205.               jb        bad_file_2     ;couldn't create file
  206.               mov       handle_2,ax    ;save file handle
  207.               lea       dx,cvt_msg_1   ;issue message
  208.               mov       ah,9           ;describing input
  209.               int       21h            ;and output files
  210.               lea       dx,file_1
  211.               int       21h
  212.               lea       dx,cvt_msg_2
  213.               int       21h
  214.               lea       dx,file_2
  215.               int       21h
  216.               lea       dx,crlf
  217.               int       21h
  218.               mov       dx,hdr_size    ;add size of EXE file header
  219.               mov       cx,0           ;and
  220.               add       dx,file_hdr+20 ;initial IP
  221.               adc       cx,0           ;to get offset of actual code
  222.               mov       bx,handle_1
  223.               mov       ax,4200h       ;set file pointer to beginning
  224.               int       21h            ;of actual code
  225.               mov       ax,code_size   ;subtract IP from code size
  226.               sub       ax,file_hdr+20 ;to give # of bytes to write
  227. check_size:   mov       code_size,ax   ;store # of bytes to write
  228.               mov       cx,512
  229.               cmp       cx,ax          ;if bytes remaining > 512
  230.               jna       read_exe       ;read 512 bytes
  231.               mov       cx,code_size   ;otherwise read remaining
  232. read_exe:     mov       bx,handle_1
  233.               lea       dx,file_buf
  234.               mov       ah,3fh         ;read EXE file
  235.               int       21h
  236.               jnb       write_com
  237.               jmp       bad_read       ;error reading
  238. write_com:    mov       bx,handle_2
  239.               lea       dx,file_buf
  240.               mov       ah,40h         ;write to output file
  241.               int       21h
  242.               jnb       next_read
  243.               jmp       bad_write      ;error writing
  244. next_read:    mov       ax,code_size   ;recall # of bytes to write
  245.               sub       ax,cx          ;subtract # of bytes written
  246.               jnz       check_size     ;to give # of bytes remaining
  247. close_files:  mov       bx,handle_1
  248.               mov       ah,3eh         ;close input file
  249.               int       21h
  250.               mov       bx,handle_2    ;close output file
  251.               int       21h
  252.               ret
  253. convert       endp
  254. sys_file      proc      near           ;change output file ext
  255.               lea       di,file_2      ;to .SYS
  256.               mov       al,'.'
  257.               repnz     scasb          ;scan for '.'
  258.               dec       di
  259.               lea       si,com_ext
  260.               mov       cx,4
  261.               repz      cmpsb          ;is ext .COM?
  262.               jnz       end_sys
  263.               lea       dx,warn_msg    ;if so issue message
  264.               mov       ah,9
  265.               int       21h
  266.               sub       di,4           ;and change it to .SYS
  267.               lea       si,sys_ext
  268.               mov       cx,4
  269.               rep       movsb
  270. end_sys:      ret
  271. sys_file      endp
  272. main:         call      init           ;get input & output file names
  273.               call      read_hdr       ;get fixed EXE file header
  274.               call      convert        ;convert file
  275.               mov       ax,4c00h       ;terminate with no return code
  276.               int       21h
  277. code          ends
  278. end           begin
  279.